package com.example.image_compress_demo;

import com.example.image_compress_demo.util.DateUtil;
import com.example.image_compress_demo.util.ImageUtil2;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.tomcat.util.codec.binary.Base64;

import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;

/**
 * @author benjamin_5
 * @Description
 * @date 2023/6/29
 */
public class PicDemo {

    public static void main(String[] args) throws Exception {
        String path = "/Users/wuhanxue/Downloads/4a439a68979a4faebeb18f2490c11cf9.jpeg";
        byte[] bytes = Files.readAllBytes(Paths.get(path));
        double fileSizeKB = bytes.length / 1024.0; // 单位转换为KB
        System.out.println("图片大小："+fileSizeKB+" KB");
        String s = imageHandle(bytes, 30);
        byte[] bytes1 = Base64.decodeBase64(s);
        double fileSizeKB1 = bytes1.length / 1024.0; // 单位转换为KB
        System.out.println("图片压缩大小："+fileSizeKB1+" KB");
        FileOutputStream fileOutputStream = new FileOutputStream(path + ".new.jpg");
        fileOutputStream.write(bytes1);
        fileOutputStream.close();
    }

    private static String imageHandle(byte[] file, Integer size) throws Exception {
        String base64Image = null;
        if(size == null){
            size = 90;
        }
        if (file.length > size * 1024) {//如果图片大于100KB
            String fileName = DateUtil.getCurTimeString(DateUtil.Format.NO_SYMBOL) + getStringRandom(8) + ".jpg";
            File distFile = new File(fileName);
            File distFile2 = null;
            InputStream in = new ByteArrayInputStream(file);
            InputStream distIn = null;
            InputStream distIn2 = null;
            ImageIcon ii = new ImageIcon(file);
            Image i = ii.getImage();
            int width = i.getWidth(null);
            int height = i.getHeight(null);
            String imageType = getPicType(file);
            ImageUtil2.cutImage(0, 0, width, height, in, distFile, imageType);
            byte[] data = null;
            try {
                distIn = new FileInputStream(distFile);
                if (distIn.available() > 90 * 1024) {//压缩之后图片大于100KB
                    double rate = 90 * 1024f / distIn.available();
                    String fileName2 = DateUtil.getCurTimeString(DateUtil.Format.NO_SYMBOL) + getStringRandom(8) + ".jpg";
                    distFile2 = new File(fileName2);
                    Thumbnails.of(distIn).scale(Math.sqrt(rate)).outputFormat("jpg").toFile(distFile2);
                    distIn2 = new FileInputStream(distFile2);
                    data = new byte[distIn2.available()];
                    distIn2.read(data);
                } else {
                    data = new byte[distIn.available()];
                    distIn.read(data);
                }
            } finally {
                if (in != null) {
                    in.close();
                }
                if (distIn != null) {
                    distIn.close();
                }
                if (distIn2 != null) {
                    distIn2.close();
                }
                if (distFile2 != null && distFile2.exists()) {
                    distFile2.delete();
                }
                if (distFile != null && distFile.exists()) {
                    distFile.delete();
                }
            }
            base64Image = Base64.encodeBase64String(data);
        } else {
            base64Image = Base64.encodeBase64String(file);
        }
        return base64Image;
    }

    private static String getPicType(byte[] file) throws Exception {
        //读取文件的前几个字节来判断图片格式
        String imageType = "jpg";
        byte[] b = Arrays.copyOf(file, 4);
        String type = byte2hex(b).toUpperCase();
        if (type.contains("FFD8FF")) {
            imageType = "jpg";
        } else if (type.contains("89504E47")) {
            imageType = "png";
        } else if (type.contains("47494638")) {
            imageType = "gif";
        } else if (type.contains("424D")) {
            imageType = "bmp";
        }
        return imageType;
    }

    /**
     * 二进制byte数组转十六进制byte数组
     * byte array to hex
     *
     * @param b byte array
     * @return hex string
     */
    public static String byte2hex(byte[] b) {
        StringBuilder hs = new StringBuilder();
        String stmp;
        for (int i = 0; i < b.length; i++) {
            stmp = Integer.toHexString(b[i] & 0xFF).toUpperCase();
            if (stmp.length() == 1) {
                hs.append("0").append(stmp);
            } else {
                hs.append(stmp);
            }
        }
        return hs.toString();
    }

    //生成随机数字和字母,
    public static String getStringRandom(int length) {
        String val = "";
        java.util.Random random = new java.util.Random();
        //参数length，表示生成几位随机数
        for (int i = 0; i < length; i++) {
            String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
            //输出字母还是数字
            if ("char".equalsIgnoreCase(charOrNum)) {
                //输出是大写字母还是小写字母
                int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;
                val += (char) (random.nextInt(26) + temp);
            } else if ("num".equalsIgnoreCase(charOrNum)) {
                val += String.valueOf(random.nextInt(10));
            }
        }
        return val;
    }
}
